package com.help10000.rms.utils

import android.app.Activity
import android.content.Context
import android.content.pm.PackageManager
import android.os.Build
import android.os.Looper
import android.util.Log
import android.view.ViewGroup
import android.widget.Toast
import androidx.core.content.ContextCompat
import com.amir.common.utils.LogUtils
import com.amir.common.utils.PermissionUtils
import com.help10000.rms.R
import com.help10000.rms.ui.activitys.OrderActivity
import com.tencent.map.geolocation.TencentLocation
import com.tencent.map.geolocation.TencentLocationListener
import com.tencent.map.geolocation.TencentLocationManager
import com.tencent.map.geolocation.TencentLocationRequest
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.suspendCancellableCoroutine
import kotlinx.coroutines.withContext
import kotlin.coroutines.resume


object LocationManager {
    private var hasRequestedPermission = false
    private var permissionResultCallback: ((Boolean) -> Unit)? = null
    private var locationSuccessCallback: (() -> Unit)? = null

    fun resetPermissionState() {
        hasRequestedPermission = false
        permissionResultCallback = null
        locationSuccessCallback = null
    }

    fun onRequestPermissionsResult(grantResults: IntArray, permissions: Array<out String>) {
        val hasFineLocation = permissions.contains(android.Manifest.permission.ACCESS_FINE_LOCATION) &&
                grantResults[permissions.indexOf(android.Manifest.permission.ACCESS_FINE_LOCATION)] == PackageManager.PERMISSION_GRANTED
        val hasCoarseLocation = permissions.contains(android.Manifest.permission.ACCESS_COARSE_LOCATION) &&
                grantResults[permissions.indexOf(android.Manifest.permission.ACCESS_COARSE_LOCATION)] == PackageManager.PERMISSION_GRANTED
        val isGranted = hasFineLocation || hasCoarseLocation
        permissionResultCallback?.invoke(isGranted)
        permissionResultCallback = null
    }

    suspend fun getLocation(context: Context, onSuccess: (() -> Unit)? = null): Pair<String, String> {
        locationSuccessCallback = onSuccess
        return getLocationInternal(context)
    }

    // 仅展示关键修改部分
    private suspend fun getLocationInternal(context: Context): Pair<String, String> {
        val activity = context as? Activity ?: run {
            LogUtils.E("定位失败：上下文不是Activity")
            return Pair("0", "0")
        }

        val rootView = activity.findViewById<ViewGroup>(android.R.id.content).getChildAt(0)

        val requiredPermissions = mutableListOf<String>().apply {
            addAll(LOCATION_PERMISSIONS)
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q && isNeedBackgroundLocation()) {
                add(ACCESS_BACKGROUND_LOCATION)
            }
        }.toTypedArray()

        if (checkPermissions(context, requiredPermissions)) {
            return getRealTimeLocation(context)
        }

        if (!hasRequestedPermission) {
            hasRequestedPermission = true
            return suspendCancellableCoroutine { continuation ->
                permissionResultCallback = { granted ->
                    CoroutineScope(Dispatchers.Main).launch {

                        if (granted) {
                            (context as? OrderActivity)?.loadData()
                            val location = getRealTimeLocation(context)
                            continuation.resume(location)
                        } else {
                            continuation.resume(Pair("0", "0"))

                        }
                    }
                }


                PermissionUtils.checkReadPermission(
                    requiredPermissions,
                    PermissionUtils.REQUEST_LOCATION,
                    activity
                )

            }
        } else {

            return Pair("0", "0")
        }
    }


    private suspend fun getRealTimeLocation(context: Context): Pair<String, String> {
        return suspendCancellableCoroutine { continuation ->
            val locationManager = TencentLocationManager.getInstance(context) ?: run {
                // 2. 在当前作用域内重新获取rootView（关键修复）
                val activity = context as? Activity
                val rootView = activity?.findViewById<ViewGroup>(android.R.id.content)?.getChildAt(0)
                if (activity != null && rootView != null) {
//                    SnackBarUtil.show(
//                        activity = activity,
//                        view = rootView,
//                        msg = "定位服务异常",
//                        tip = "无法初始化定位服务，请稍后重试"
//                    )
                } else {
                    Toast.makeText(context, "定位服务初始化失败", Toast.LENGTH_SHORT).show()
                }
                continuation.resume(Pair("0", "0"))
                return@suspendCancellableCoroutine
            }

            val request = TencentLocationRequest.create().apply {
                interval = 0
                isAllowGPS = true
                requestLevel = TencentLocationRequest.REQUEST_LEVEL_GEO
            }

            val listener = object : TencentLocationListener {
                override fun onStatusUpdate(provider: String?, status: Int, message: String?) {
                    locationManager.removeUpdates(this)
                    if (!continuation.isCancelled) {
                        LogUtils.E("定位状态异常：$message")
                        // 3. 在此作用域内重新获取rootView
                        val activity = context as? Activity
                        val rootView = activity?.findViewById<ViewGroup>(android.R.id.content)?.getChildAt(0)
                        if (activity != null && rootView != null) {
//                            SnackBarUtil.show(
//                                activity = activity,
//                                view = rootView,
//                                msg = "定位失败",
//                                tip = "状态异常：$message"
//                            )
                        }
                        continuation.resume(Pair("0", "0"))
                    }
                }

                override fun onLocationChanged(location: TencentLocation?, errorCode: Int, message: String?) {
                    locationManager.removeUpdates(this)
                    if (continuation.isCancelled) {
                        LogUtils.E("定位已取消，不处理结果")
                        return
                    }

                    if (location != null && errorCode == TencentLocation.ERROR_OK) {
                        val latValid = location.latitude.isValid()
                        val lngValid = location.longitude.isLongitudeValid()

                        if (latValid && lngValid) {
                            val result = Pair(
                                location.latitude.toString(),
                                location.longitude.toString()
                            )
                            locationSuccessCallback?.invoke()
                            continuation.resume(result)
                        } else {
                            // 4. 重新获取rootView
                            val activity = context as? Activity
                            val rootView = activity?.findViewById<ViewGroup>(android.R.id.content)?.getChildAt(0)
                            if (activity != null && rootView != null) {
//                                SnackBarUtil.show(
//                                    activity = activity,
//                                    view = rootView,
//                                    msg = "定位无效",
//                                    tip = "无法获取有效位置信息",
//                                    2000
//                                )
                            }
                            continuation.resume(Pair("0", "0"))
                        }
                    } else {
                        // 5. 重新获取rootView
                        val activity = context as? Activity
                        val rootView = activity?.findViewById<ViewGroup>(android.R.id.content)?.getChildAt(0)
                        if (activity != null && rootView != null) {
//                            SnackBarUtil.show(
//                                activity = activity,
//                                view = rootView,
//                                msg = "定位失败",
//                                tip = "请检查网络和定位设置",
//                                2000
//                            )
                        }
                        continuation.resume(Pair("0", "0"))
                    }
                }

                private fun Double.isValid(): Boolean {
                    return this >= -90.0 && this <= 90.0
                }

                private fun Double.isLongitudeValid(): Boolean {
                    return this >= -180.0 && this <= 180.0
                }
            }

            val requestCode = locationManager.requestSingleFreshLocation(request, listener, Looper.getMainLooper())
            if (requestCode < 0) {
                LogUtils.E("定位请求发起失败，code=$requestCode")
                locationManager.removeUpdates(listener)
                // 6. 重新获取rootView
                val activity = context as? Activity
                val rootView = activity?.findViewById<ViewGroup>(android.R.id.content)?.getChildAt(0)
                if (activity != null && rootView != null) {
//                    SnackBarUtil.show(
//                        activity = activity,
//                        view = rootView,
//                        msg = "定位请求失败",
//                        tip = "无法发起定位请求，请重试",
//                        2000
//                    )
                }
                continuation.resume(Pair("0", "0"))
            }

            continuation.invokeOnCancellation {
                locationManager.removeUpdates(listener)
            }
        }
    }

    fun getLocationForJS(context: Context, callback: (String) -> Unit) {
        CoroutineScope(Dispatchers.IO).launch {
            val (lat, lng) = getLocationInternal(context)
            val json = if (lat != "0" && lng != "0") {
                """{"code":1,"msg":"实时定位成功","result":{"lng":"$lng","lat":"$lat"}}"""
            } else {
                """{"code":0,"msg":"实时定位失败","result":{"lng":"0","lat":"0"}}"""
            }
            withContext(Dispatchers.Main) {
                callback(json)
            }
        }
    }

    private fun checkPermissions(context: Context, permissions: Array<String>): Boolean {
        return permissions.all {
            ContextCompat.checkSelfPermission(context, it) == PackageManager.PERMISSION_GRANTED
        }
    }

    private fun isNeedBackgroundLocation(): Boolean {
        return false
    }

    private val LOCATION_PERMISSIONS = arrayOf(
        android.Manifest.permission.ACCESS_FINE_LOCATION,
        android.Manifest.permission.ACCESS_COARSE_LOCATION
    )

    private const val ACCESS_BACKGROUND_LOCATION = android.Manifest.permission.ACCESS_BACKGROUND_LOCATION
}
